using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Text;
using System.Threading;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Xml;

using ViewOnCore.Helper.Debug;
using ViewOnCore.Helper.WPF;
using ViewOn.Helper.IO;
using ViewOn.AddIns;
using ViewOn.AddInsHostContract;
using ViewOn.AddInsHostContract.Media;
using ViewOnCore.HostContract.Media;
using ViewOnCore.Device;
using ViewOnCore.HostContract.Tasks;
using ViewOnCore.HostContract;
using ViewOnCore.Helper.Collection;

namespace ViewOn.Kernel
{

    static public class MediaKernel
    {

        #region Variables

        static private string _webURL;

        static private bool _mustCheckForAssociations = false;

        //---- Initialization
        static private bool _isUIInitialized = false;

        #endregion

        #region Initialize

        static public void Initialize()
        {
            //---- Associations
            InitializeAssociations();

            _webURL = ConfigurationSettings.AppSettings["WebURL"];

            if (!Directory.Exists(Host.SettingsService.CachePath))
                Directory.CreateDirectory(Host.SettingsService.CachePath);
        }

        #endregion

        #region InitializeAssociations

        // http://support.microsoft.com/kb/316992

        static private void InitializeAssociations()
        {
            if (!Host.SettingsService.CheckAssociationsAtStartup)
                return;

            foreach (string key in Host.MediaService.SupportedMusicExtensions.Keys)
                if (!Host.MediaService.IsMediaFileAssociated(key))
                {
                    _mustCheckForAssociations = true;
                    return;
                }
            foreach (string key in Host.MediaService.SupportedVideoExtensions.Keys)
                if (!Host.MediaService.IsMediaFileAssociated(key))
                {
                    _mustCheckForAssociations = true;
                    return;
                }
            foreach (string key in Host.MediaService.SupportedRadioExtensions.Keys)
                if (!Host.MediaService.IsMediaFileAssociated(key))
                {
                    _mustCheckForAssociations = true;
                    return;
                }
        }

        static public bool MustCheckForAssociations
        {
            get
            {
                return _mustCheckForAssociations;
            }
        }

        #endregion

        #region Command line file

        static private string _commandLineFile = null;

        static public void InitializeCommandLineFile(string filePath)
        {
            _commandLineFile = filePath;
        }

        static private bool ExecuteCommandLineFile()
        {
            if (_commandLineFile == null)
                return false;

            MediaData mediaData = null;

            if (Host.MediaService.IsSupportedMusicFile(_commandLineFile))
                mediaData = Music.FromFile(_commandLineFile);
            else if (Host.MediaService.IsSupportedRadioFile(_commandLineFile))
                mediaData = Radio.FromFile(_commandLineFile);
            else if (Host.MediaService.IsSupportedVideoFile(_commandLineFile))
                mediaData = Video.FromFile(_commandLineFile);

            if (mediaData != null)
            {
                Host.SendCommand(null, HostCommandIds.PlayMediaData, mediaData);
                return true;
            }

            return false;
        }

        #endregion

        #region Properties

        static public string WebURL
        {
            get
            {
                return _webURL;
            }
        }

        #endregion

        #region FindDeviceFeatureByType

        static public MediaFeature FindDeviceFeatureByType(Type type)
        {
            foreach (MediaDevice device in Host.MediaService.MediaDevices)
                foreach (MediaFeature feature in device.MediaFeatures)
                    if (feature.GetType().Equals(type))
                        return feature;

            return null;
        }

        #endregion

        #region OnUIInitialized

        static public void OnUIInitialized()
        {
            if (_isUIInitialized)
                return;
            _isUIInitialized = true;

            //---- auto start file
            if (!ExecuteCommandLineFile())
                Host.MediaService.ActivateMediaDevice(null, null, null);

            Host.OnApplicationInitialized();
        }

        #endregion

    }

    #region PlayMediaKernelTask

    sealed public class PlayMediaKernelTask : Task
    {
        private MediaData _mediaData;
        private bool _isCanceled = false;

        public PlayMediaKernelTask(MediaData mediaData)
        {
            _mediaData = mediaData;
        }

        public override void Execute()
        {
            Music music = _mediaData as Music;
            Radio radio = _mediaData as Radio;
            Video video = _mediaData as Video;

            bool isPlayingOk = false;
            if (music != null)
                isPlayingOk = BassPlayer.PlayFile(music.Path);
            else if (radio != null)
                isPlayingOk = BassPlayer.PlayUrl(radio.StreamUrl);
            else if (video != null)
                isPlayingOk = true;

            if (_isCanceled)
                return;

            // Notify
            if (isPlayingOk)
                ((MediaService)Host.MediaService).OnMediaDataConnected();
            else
            {
                Host.MediaService.Stop();
                ((MediaService)Host.MediaService).OnMediaDataCannotConnect();
            }
        }

        override public void Cancel()
        {
            _isCanceled = true;

            // Cancel the current play
            PlayTicket ticket = BassPlayer.CurrentPlayTicket;
            if (ticket != null)
                ticket.Cancel = true;
        }

        override public string Message
        {
            get
            {
                if (_mediaData is Radio)
                    return "Connecting to radio service...";

                return "";
            }
        }
    }

    #endregion

}
